#include "inputsimulator.h"
#include <QCursor>
#include <QGuiApplication>
#include <QScreen>
#include <QThread>

#ifdef Q_OS_WIN
#include <windows.h>
#endif

#ifdef Q_OS_LINUX
#include <X11/Xlib.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
#endif

#ifdef Q_OS_MACOS
#include <ApplicationServices/ApplicationServices.h>
#endif

InputSimulator::InputSimulator(QObject *parent) : QObject(parent), initialized(false)
{
#ifdef Q_OS_LINUX
    display = nullptr;
#endif
}

InputSimulator::~InputSimulator()
{
#ifdef Q_OS_LINUX
    cleanupLinux();
#endif
}

bool InputSimulator::initialize()
{
    if (initialized) {
        return true;
    }

#ifdef Q_OS_WIN
    initWindows();
#endif

#ifdef Q_OS_LINUX
    initLinux();
#endif

#ifdef Q_OS_MACOS
    initMacOS();
#endif

    // 获取当前光标位置
    currentPos = QCursor::pos();
    
    LOG_INFO("输入模拟器初始化完成");
    initialized = true;
    return initialized;
}

bool InputSimulator::moveMouse(int x, int y)
{
    if (!initialized) {
        LOG_ERROR("输入模拟器未初始化");
        return false;
    }

    // 更新当前鼠标位置
    currentPos = QPoint(x, y);

#ifdef Q_OS_WIN
    // Windows实现
    SetCursorPos(x, y);
    return true;
#endif

#ifdef Q_OS_LINUX
    // Linux实现
    if (display) {
        XTestFakeMotionEvent(static_cast<Display*>(display), 0, x, y, 0);
        XFlush(static_cast<Display*>(display));
        return true;
    }
    return false;
#endif

#ifdef Q_OS_MACOS
    // macOS实现
    CGPoint point;
    point.x = x;
    point.y = y;
    CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, point, 0);
    CGEventPost(kCGHIDEventTap, event);
    CFRelease(event);
    return true;
#endif

    // 其他平台
    LOG_WARNING("当前平台不支持鼠标控制");
    return false;
}

bool InputSimulator::mousePress(int x, int y, int button)
{
    if (!initialized) {
        LOG_ERROR("输入模拟器未初始化");
        return false;
    }

    // 先移动鼠标到指定位置
    moveMouse(x, y);

#ifdef Q_OS_WIN
    // Windows实现
    DWORD winButton = 0;
    switch (button) {
    case 1: // 左键
        winButton = MOUSEEVENTF_LEFTDOWN;
        break;
    case 2: // 右键
        winButton = MOUSEEVENTF_RIGHTDOWN;
        break;
    case 3: // 中键
        winButton = MOUSEEVENTF_MIDDLEDOWN;
        break;
    default:
        return false;
    }

    INPUT input = {0};
    input.type = INPUT_MOUSE;
    input.mi.dwFlags = winButton;
    SendInput(1, &input, sizeof(INPUT));
    return true;
#endif

#ifdef Q_OS_LINUX
    // Linux实现
    if (display) {
        int xButton = mapMouseButton(button);
        if (xButton > 0) {
            XTestFakeButtonEvent(static_cast<Display*>(display), xButton, True, 0);
            XFlush(static_cast<Display*>(display));
            return true;
        }
    }
    return false;
#endif

#ifdef Q_OS_MACOS
    // macOS实现
    CGEventType eventType;
    CGMouseButton mouseButton;
    
    switch (button) {
    case 1: // 左键
        eventType = kCGEventLeftMouseDown;
        mouseButton = kCGMouseButtonLeft;
        break;
    case 2: // 右键
        eventType = kCGEventRightMouseDown;
        mouseButton = kCGMouseButtonRight;
        break;
    case 3: // 中键
        eventType = kCGEventOtherMouseDown;
        mouseButton = kCGMouseButtonCenter;
        break;
    default:
        return false;
    }
    
    CGPoint point;
    point.x = x;
    point.y = y;
    CGEventRef event = CGEventCreateMouseEvent(NULL, eventType, point, mouseButton);
    CGEventPost(kCGHIDEventTap, event);
    CFRelease(event);
    return true;
#endif

    // 其他平台
    LOG_WARNING("当前平台不支持鼠标控制");
    return false;
}

bool InputSimulator::mouseRelease(int x, int y, int button)
{
    if (!initialized) {
        LOG_ERROR("输入模拟器未初始化");
        return false;
    }

#ifdef Q_OS_WIN
    // Windows实现
    DWORD winButton = 0;
    switch (button) {
    case 1: // 左键
        winButton = MOUSEEVENTF_LEFTUP;
        break;
    case 2: // 右键
        winButton = MOUSEEVENTF_RIGHTUP;
        break;
    case 3: // 中键
        winButton = MOUSEEVENTF_MIDDLEUP;
        break;
    default:
        return false;
    }

    INPUT input = {0};
    input.type = INPUT_MOUSE;
    input.mi.dwFlags = winButton;
    SendInput(1, &input, sizeof(INPUT));
    return true;
#endif

#ifdef Q_OS_LINUX
    // Linux实现
    if (display) {
        int xButton = mapMouseButton(button);
        if (xButton > 0) {
            XTestFakeButtonEvent(static_cast<Display*>(display), xButton, False, 0);
            XFlush(static_cast<Display*>(display));
            return true;
        }
    }
    return false;
#endif

#ifdef Q_OS_MACOS
    // macOS实现
    CGEventType eventType;
    CGMouseButton mouseButton;
    
    switch (button) {
    case 1: // 左键
        eventType = kCGEventLeftMouseUp;
        mouseButton = kCGMouseButtonLeft;
        break;
    case 2: // 右键
        eventType = kCGEventRightMouseUp;
        mouseButton = kCGMouseButtonRight;
        break;
    case 3: // 中键
        eventType = kCGEventOtherMouseUp;
        mouseButton = kCGMouseButtonCenter;
        break;
    default:
        return false;
    }
    
    CGPoint point;
    point.x = x;
    point.y = y;
    CGEventRef event = CGEventCreateMouseEvent(NULL, eventType, point, mouseButton);
    CGEventPost(kCGHIDEventTap, event);
    CFRelease(event);
    return true;
#endif

    // 其他平台
    (void)x; // 防止未使用参数警告
    (void)y; // 防止未使用参数警告
    LOG_WARNING("当前平台不支持鼠标控制");
    return false;
}

bool InputSimulator::mouseClick(int x, int y, int button)
{
    if (!mousePress(x, y, button)) {
        return false;
    }
    
    // 短暂延迟，模拟真实点击
    QThread::msleep(20);
    
    return mouseRelease(x, y, button);
}

bool InputSimulator::keyPress(int key)
{
    if (!initialized) {
        LOG_ERROR("输入模拟器未初始化");
        return false;
    }

    int systemKey = mapKey(key);
    if (systemKey == 0) {
        LOG_WARNING(QString("无法映射Qt键: %1").arg(key));
        return false;
    }

#ifdef Q_OS_WIN
    // Windows实现
    INPUT input = {0};
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = systemKey;
    SendInput(1, &input, sizeof(INPUT));
    return true;
#endif

#ifdef Q_OS_LINUX
    // Linux实现
    if (display) {
        XTestFakeKeyEvent(static_cast<Display*>(display), systemKey, True, 0);
        XFlush(static_cast<Display*>(display));
        return true;
    }
    return false;
#endif

#ifdef Q_OS_MACOS
    // macOS实现
    CGEventRef event = CGEventCreateKeyboardEvent(NULL, systemKey, true);
    CGEventPost(kCGHIDEventTap, event);
    CFRelease(event);
    return true;
#endif

    // 其他平台
    LOG_WARNING("当前平台不支持键盘控制");
    return false;
}

bool InputSimulator::keyRelease(int key)
{
    if (!initialized) {
        LOG_ERROR("输入模拟器未初始化");
        return false;
    }

    int systemKey = mapKey(key);
    if (systemKey == 0) {
        LOG_WARNING(QString("无法映射Qt键: %1").arg(key));
        return false;
    }

#ifdef Q_OS_WIN
    // Windows实现
    INPUT input = {0};
    input.type = INPUT_KEYBOARD;
    input.ki.wVk = systemKey;
    input.ki.dwFlags = KEYEVENTF_KEYUP;
    SendInput(1, &input, sizeof(INPUT));
    return true;
#endif

#ifdef Q_OS_LINUX
    // Linux实现
    if (display) {
        XTestFakeKeyEvent(static_cast<Display*>(display), systemKey, False, 0);
        XFlush(static_cast<Display*>(display));
        return true;
    }
    return false;
#endif

#ifdef Q_OS_MACOS
    // macOS实现
    CGEventRef event = CGEventCreateKeyboardEvent(NULL, systemKey, false);
    CGEventPost(kCGHIDEventTap, event);
    CFRelease(event);
    return true;
#endif

    // 其他平台
    LOG_WARNING("当前平台不支持键盘控制");
    return false;
}

bool InputSimulator::keyClick(int key)
{
    if (!keyPress(key)) {
        return false;
    }
    
    // 短暂延迟，模拟真实按键
    QThread::msleep(20);
    
    return keyRelease(key);
}

int InputSimulator::mapKey(int qtKey)
{
#ifdef Q_OS_WIN
    // Qt键码到Windows虚拟键码的映射
    switch (qtKey) {
    case Qt::Key_A: return 'A';
    case Qt::Key_B: return 'B';
    case Qt::Key_C: return 'C';
    case Qt::Key_D: return 'D';
    case Qt::Key_E: return 'E';
    case Qt::Key_F: return 'F';
    case Qt::Key_G: return 'G';
    case Qt::Key_H: return 'H';
    case Qt::Key_I: return 'I';
    case Qt::Key_J: return 'J';
    case Qt::Key_K: return 'K';
    case Qt::Key_L: return 'L';
    case Qt::Key_M: return 'M';
    case Qt::Key_N: return 'N';
    case Qt::Key_O: return 'O';
    case Qt::Key_P: return 'P';
    case Qt::Key_Q: return 'Q';
    case Qt::Key_R: return 'R';
    case Qt::Key_S: return 'S';
    case Qt::Key_T: return 'T';
    case Qt::Key_U: return 'U';
    case Qt::Key_V: return 'V';
    case Qt::Key_W: return 'W';
    case Qt::Key_X: return 'X';
    case Qt::Key_Y: return 'Y';
    case Qt::Key_Z: return 'Z';
    // 数字键盘
    case Qt::Key_0: return '0';
    case Qt::Key_1: return '1';
    case Qt::Key_2: return '2';
    case Qt::Key_3: return '3';
    case Qt::Key_4: return '4';
    case Qt::Key_5: return '5';
    case Qt::Key_6: return '6';
    case Qt::Key_7: return '7';
    case Qt::Key_8: return '8';
    case Qt::Key_9: return '9';
    case Qt::Key_Return: return VK_RETURN;
    case Qt::Key_Enter: return VK_RETURN;  // 数字键盘的回车键
    case Qt::Key_Escape: return VK_ESCAPE;
    case Qt::Key_Tab: return VK_TAB;
    case Qt::Key_Backspace: return VK_BACK;
    case Qt::Key_Shift: return VK_SHIFT;
    case Qt::Key_Control: return VK_CONTROL;
    case Qt::Key_Alt: return VK_MENU;
    case Qt::Key_Left: return VK_LEFT;
    case Qt::Key_Right: return VK_RIGHT;
    case Qt::Key_Up: return VK_UP;
    case Qt::Key_Down: return VK_DOWN;
    }
    return 0;
#endif

#ifdef Q_OS_LINUX
    // Qt键码到X11键码的映射
    switch (qtKey) {
    case Qt::Key_A: return XKeysymToKeycode(static_cast<Display*>(display), XK_a);
    case Qt::Key_B: return XKeysymToKeycode(static_cast<Display*>(display), XK_b);
    case Qt::Key_C: return XKeysymToKeycode(static_cast<Display*>(display), XK_c);
    case Qt::Key_D: return XKeysymToKeycode(static_cast<Display*>(display), XK_d);
    case Qt::Key_E: return XKeysymToKeycode(static_cast<Display*>(display), XK_e);
    case Qt::Key_F: return XKeysymToKeycode(static_cast<Display*>(display), XK_f);
    case Qt::Key_G: return XKeysymToKeycode(static_cast<Display*>(display), XK_g);
    case Qt::Key_H: return XKeysymToKeycode(static_cast<Display*>(display), XK_h);
    case Qt::Key_I: return XKeysymToKeycode(static_cast<Display*>(display), XK_i);
    case Qt::Key_J: return XKeysymToKeycode(static_cast<Display*>(display), XK_j);
    case Qt::Key_K: return XKeysymToKeycode(static_cast<Display*>(display), XK_k);
    case Qt::Key_L: return XKeysymToKeycode(static_cast<Display*>(display), XK_l);
    case Qt::Key_M: return XKeysymToKeycode(static_cast<Display*>(display), XK_m);
    case Qt::Key_N: return XKeysymToKeycode(static_cast<Display*>(display), XK_n);
    case Qt::Key_O: return XKeysymToKeycode(static_cast<Display*>(display), XK_o);
    case Qt::Key_P: return XKeysymToKeycode(static_cast<Display*>(display), XK_p);
    case Qt::Key_Q: return XKeysymToKeycode(static_cast<Display*>(display), XK_q);
    case Qt::Key_R: return XKeysymToKeycode(static_cast<Display*>(display), XK_r);
    case Qt::Key_S: return XKeysymToKeycode(static_cast<Display*>(display), XK_s);
    case Qt::Key_T: return XKeysymToKeycode(static_cast<Display*>(display), XK_t);
    case Qt::Key_U: return XKeysymToKeycode(static_cast<Display*>(display), XK_u);
    case Qt::Key_V: return XKeysymToKeycode(static_cast<Display*>(display), XK_v);
    case Qt::Key_W: return XKeysymToKeycode(static_cast<Display*>(display), XK_w);
    case Qt::Key_X: return XKeysymToKeycode(static_cast<Display*>(display), XK_x);
    case Qt::Key_Y: return XKeysymToKeycode(static_cast<Display*>(display), XK_y);
    case Qt::Key_Z: return XKeysymToKeycode(static_cast<Display*>(display), XK_z);
    case Qt::Key_0: return XKeysymToKeycode(static_cast<Display*>(display), XK_0);
    case Qt::Key_1: return XKeysymToKeycode(static_cast<Display*>(display), XK_1);
    case Qt::Key_2: return XKeysymToKeycode(static_cast<Display*>(display), XK_2);
    case Qt::Key_3: return XKeysymToKeycode(static_cast<Display*>(display), XK_3);
    case Qt::Key_4: return XKeysymToKeycode(static_cast<Display*>(display), XK_4);
    case Qt::Key_5: return XKeysymToKeycode(static_cast<Display*>(display), XK_5);
    case Qt::Key_6: return XKeysymToKeycode(static_cast<Display*>(display), XK_6);
    case Qt::Key_7: return XKeysymToKeycode(static_cast<Display*>(display), XK_7);
    case Qt::Key_8: return XKeysymToKeycode(static_cast<Display*>(display), XK_8);
    case Qt::Key_9: return XKeysymToKeycode(static_cast<Display*>(display), XK_9);
    case Qt::Key_Return: return XKeysymToKeycode(static_cast<Display*>(display), XK_Return);
    case Qt::Key_Enter: return XKeysymToKeycode(static_cast<Display*>(display), XK_KP_Enter); // 数字键盘的回车键
    case Qt::Key_Escape: return XKeysymToKeycode(static_cast<Display*>(display), XK_Escape);
    case Qt::Key_Tab: return XKeysymToKeycode(static_cast<Display*>(display), XK_Tab);
    case Qt::Key_Backspace: return XKeysymToKeycode(static_cast<Display*>(display), XK_BackSpace);
    case Qt::Key_Shift: return XKeysymToKeycode(static_cast<Display*>(display), XK_Shift_L);
    case Qt::Key_Control: return XKeysymToKeycode(static_cast<Display*>(display), XK_Control_L);
    case Qt::Key_Alt: return XKeysymToKeycode(static_cast<Display*>(display), XK_Alt_L);
    case Qt::Key_Left: return XKeysymToKeycode(static_cast<Display*>(display), XK_Left);
    case Qt::Key_Right: return XKeysymToKeycode(static_cast<Display*>(display), XK_Right);
    case Qt::Key_Up: return XKeysymToKeycode(static_cast<Display*>(display), XK_Up);
    case Qt::Key_Down: return XKeysymToKeycode(static_cast<Display*>(display), XK_Down);
    }
    return 0;
#endif

#ifdef Q_OS_MACOS
    // Qt键码到macOS键码的映射
    switch (qtKey) {
    case Qt::Key_A: return kVK_ANSI_A;
    case Qt::Key_B: return kVK_ANSI_B;
    case Qt::Key_C: return kVK_ANSI_C;
    case Qt::Key_D: return kVK_ANSI_D;
    case Qt::Key_E: return kVK_ANSI_E;
    case Qt::Key_F: return kVK_ANSI_F;
    case Qt::Key_G: return kVK_ANSI_G;
    case Qt::Key_H: return kVK_ANSI_H;
    case Qt::Key_I: return kVK_ANSI_I;
    case Qt::Key_J: return kVK_ANSI_J;
    case Qt::Key_K: return kVK_ANSI_K;
    case Qt::Key_L: return kVK_ANSI_L;
    case Qt::Key_M: return kVK_ANSI_M;
    case Qt::Key_N: return kVK_ANSI_N;
    case Qt::Key_O: return kVK_ANSI_O;
    case Qt::Key_P: return kVK_ANSI_P;
    case Qt::Key_Q: return kVK_ANSI_Q;
    case Qt::Key_R: return kVK_ANSI_R;
    case Qt::Key_S: return kVK_ANSI_S;
    case Qt::Key_T: return kVK_ANSI_T;
    case Qt::Key_U: return kVK_ANSI_U;
    case Qt::Key_V: return kVK_ANSI_V;
    case Qt::Key_W: return kVK_ANSI_W;
    case Qt::Key_X: return kVK_ANSI_X;
    case Qt::Key_Y: return kVK_ANSI_Y;
    case Qt::Key_Z: return kVK_ANSI_Z;
    case Qt::Key_0: return kVK_ANSI_0;
    case Qt::Key_1: return kVK_ANSI_1;
    case Qt::Key_2: return kVK_ANSI_2;
    case Qt::Key_3: return kVK_ANSI_3;
    case Qt::Key_4: return kVK_ANSI_4;
    case Qt::Key_5: return kVK_ANSI_5;
    case Qt::Key_6: return kVK_ANSI_6;
    case Qt::Key_7: return kVK_ANSI_7;
    case Qt::Key_8: return kVK_ANSI_8;
    case Qt::Key_9: return kVK_ANSI_9;
    case Qt::Key_Return: return kVK_Return;
    case Qt::Key_Enter: return kVK_ANSI_KeypadEnter; // 数字键盘的回车键
    case Qt::Key_Escape: return kVK_Escape;
    case Qt::Key_Tab: return kVK_Tab;
    case Qt::Key_Backspace: return kVK_Delete;
    case Qt::Key_Shift: return kVK_Shift;
    case Qt::Key_Control: return kVK_Control;
    case Qt::Key_Alt: return kVK_Option;
    case Qt::Key_Left: return kVK_LeftArrow;
    case Qt::Key_Right: return kVK_RightArrow;
    case Qt::Key_Up: return kVK_UpArrow;
    case Qt::Key_Down: return kVK_DownArrow;
    }
    return 0;
#endif

    // 默认情况
    return qtKey;
}

int InputSimulator::mapMouseButton(int qtButton)
{
#ifdef Q_OS_LINUX
    // Qt鼠标按钮到X11鼠标按钮的映射
    switch (qtButton) {
    case 1: return 1; // 左键
    case 2: return 3; // 右键
    case 3: return 2; // 中键
    }
    return 0;
#endif

    // 其他平台默认返回原始值
    return qtButton;
}

#ifdef Q_OS_WIN
void InputSimulator::initWindows()
{
    LOG_INFO("初始化Windows输入模拟器");
}
#endif

#ifdef Q_OS_LINUX
void InputSimulator::initLinux()
{
    LOG_INFO("初始化Linux输入模拟器");
    display = XOpenDisplay(NULL);
    if (!display) {
        LOG_ERROR("无法打开X11显示");
    }
}

void InputSimulator::cleanupLinux()
{
    if (display) {
        XCloseDisplay(static_cast<Display*>(display));
        display = nullptr;
    }
}
#endif

#ifdef Q_OS_MACOS
void InputSimulator::initMacOS()
{
    LOG_INFO("初始化macOS输入模拟器");
}
#endif 